// Fill out your copyright notice in the Description page of Project Settings.


#include "UintAccessLibrary.h"
#include "Serialization/BufferArchive.h"
#include "Serialization/MemoryReader.h"
#include "Serialization/ArchiveSaveCompressedProxy.h"
#include "Serialization/ArchiveLoadCompressedProxy.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"

DEFINE_LOG_CATEGORY(UintAccessLibraryLog);

bool UUintAccessLibrary::SaveStringToFile(FString Content, FString filename)
{
	return SaveString(Content, *filename);
}

bool UUintAccessLibrary::LoadFileToString(FString& Content, FString filename)
{
	return LoadString(Content, *filename);
}

bool UUintAccessLibrary::SaveStringArrayToFile(TArray<FString> Content, FString filename)
{
	return SaveStringArray(Content, *filename);
}

bool UUintAccessLibrary::LoadFileToStringArray(TArray<FString>& Content, FString filename)
{
	return LoadStringArray(Content, *filename);
}

bool UUintAccessLibrary::SaveString(FString& Content, const TCHAR* Filename)
{
	return SaveData(Content, Filename);
}

bool UUintAccessLibrary::LoadString(FString& Content, const TCHAR* Filename)
{
	return LoadData(Content, Filename);
}

bool UUintAccessLibrary::SaveStringArray(TArray<FString>& Contents, const TCHAR* Filename)
{
	return SaveData(Contents, Filename);
}

bool UUintAccessLibrary::LoadStringArray(TArray<FString>& Contents, const TCHAR* Filename)
{
	return LoadData(Contents, Filename);
}


template<typename AccessedType>
inline bool UUintAccessLibrary::SaveData(AccessedType& Content, const TCHAR* Filename)
{
	FBufferArchive ToBinary;
	ToBinary << Content;

	TArray<uint8> CompressedData;
	FArchiveSaveCompressedProxy Compressor = FArchiveSaveCompressedProxy(CompressedData, ECompressionFlags::COMPRESS_ZLIB);
	Compressor << ToBinary;

	Compressor.Flush();

	bool Result = FFileHelper::SaveArrayToFile(CompressedData, Filename);
	if (Result)
	{
		UE_LOG(UintAccessLibraryLog, Log, TEXT("%s Save Finished !"), Filename);
	}
	else
	{
		UE_LOG(UintAccessLibraryLog, Error, TEXT("%s Save Fiald !"), Filename);
	}

	Compressor.FlushCache();
	CompressedData.Empty();
	ToBinary.FlushCache();
	ToBinary.Empty();
	ToBinary.Close();

	return Result;
}

template<typename AccessedType>
bool UUintAccessLibrary::LoadData(AccessedType& Content, const TCHAR* Filename)
{
	TArray<uint8> CompressedData;
	if (!FFileHelper::LoadFileToArray(CompressedData, Filename))
	{
		UE_LOG(UintAccessLibraryLog, Error, TEXT("%s Load Fiald !"), Filename);
		return false;
	}

	FArchiveLoadCompressedProxy Decompressor = FArchiveLoadCompressedProxy(CompressedData, ECompressionFlags::COMPRESS_ZLIB);

	FBufferArchive DecompressedBinaryArray;
	Decompressor << DecompressedBinaryArray;

	FMemoryReader FromBinary = FMemoryReader(DecompressedBinaryArray, true);
	FromBinary << Content;

	CompressedData.Empty();
	Decompressor.FlushCache();
	FromBinary.FlushCache();
	DecompressedBinaryArray.Empty();
	DecompressedBinaryArray.Close();

	UE_LOG(UintAccessLibraryLog, Log, TEXT("%s Load Finished !"), Filename);

	return true;
}
